package com.yytek.nmp.service.impl;

import java.util.ArrayList;
import java.util.List;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.yytek.common.core.domain.R;
import com.yytek.common.core.utils.DateUtils;
import com.yytek.nmp.domain.IotModelDefine;
import com.yytek.nmp.mapper.IotModelDefineMapper;
import com.yytek.tddb.api.RemoteTdEngineService;
import com.yytek.tddb.api.domain.Fields;
import com.yytek.tddb.api.domain.SuperTableDto;
import com.yytek.tddb.api.enums.DataTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.yytek.nmp.mapper.IotProductInfoMapper;
import com.yytek.nmp.domain.IotProductInfo;
import com.yytek.nmp.service.IIotProductInfoService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 产品Service业务层处理
 * 
 * @author yytek-iot
 * @date 2022-07-05
 */
@Service
@Slf4j
public class IotProductInfoServiceImpl implements IIotProductInfoService 
{
    @Autowired
    private IotProductInfoMapper iotProductInfoMapper;
    @Autowired
    private RemoteTdEngineService tdEngineService;
    @Autowired
    private IotModelDefineMapper modelDefineMapper;
    /**
     * 查询产品
     * 
     * @param id 产品主键
     * @return 产品
     */
    @Override
    public IotProductInfo selectIotProductInfoById(Integer id)
    {
        return iotProductInfoMapper.selectIotProductInfoById(id);
    }

    /**
     * 查询产品列表
     * 
     * @param iotProductInfo 产品
     * @return 产品
     */
    @Override
    public List<IotProductInfo> selectIotProductInfoList(IotProductInfo iotProductInfo)
    {
        return iotProductInfoMapper.selectIotProductInfoList(iotProductInfo);
    }

    /**
     * 新增产品
     * 
     * @param iotProductInfo 产品
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertIotProductInfo(IotProductInfo iotProductInfo)
    {
        iotProductInfo.setCreateTime(DateUtils.getNowDate());
        int rows = iotProductInfoMapper.insertIotProductInfo(iotProductInfo);
        if (rows > 0) {
            //根据产品物模型生成字段
            createSuperTable(iotProductInfo);
        }
        return rows;
    }

    /**
     * 根据产品信息创建时序数据库超级表
     * @param iotProductInfo
     */
    public void createSuperTable(IotProductInfo iotProductInfo) {
        SuperTableDto superTableDto = new SuperTableDto();
        superTableDto.setSuperTableName(iotProductInfo.getProductKey());
        //查询物模型属性信息
        IotModelDefine modelDefine =  modelDefineMapper.selectIotModelDefineById(iotProductInfo.getModelId());
        JSONArray propertiesArray = JSON.parseArray(modelDefine.getProperties());

        //如果服务下属性值为空，没必要为该服务创建超级表，跳过该循环，进入下个服务
        if (!propertiesArray.isEmpty()) {
            //超级表的表结构（业务相关）
            List<Fields> schemaFields = new ArrayList<>();
            //超级表第一个字段数据类型必须为时间戳,默认Ts为当前系统时间
            Fields tsColumn = new Fields();
            tsColumn.setFieldName("ts");
            tsColumn.setDataType(DataTypeEnum.TIMESTAMP);
            schemaFields.add(tsColumn);
            //超级表第二个字段为事件发生时间数据类型必须为时间戳
            Fields eventTimeColumn = new Fields();
            eventTimeColumn.setFieldName("event_time");
            eventTimeColumn.setDataType(DataTypeEnum.TIMESTAMP);
            schemaFields.add(eventTimeColumn);
            //根据属性对象列表循环构建超级表表结构
            for (int j = 0; j < propertiesArray.size(); j++) {
                JSONObject propertie = propertiesArray.getJSONObject(j);
                //获取字段名称
                String filedName = (String) propertie.get("identifier");
                //获取该属性数据类型
                JSONObject datatypeJson =  propertie.getJSONObject("dataType");
                String datatype = (String) datatypeJson.get("type");
                //获取该属性的数据大小,默认100
                Integer size = 100;
                if(datatypeJson.get("maxlength") != null){
                    size = Integer.valueOf(datatypeJson.get("maxlength").toString()) ;
                }
                //添加超级表表结构字段
                Fields fields = new Fields(filedName, datatype, size);
                schemaFields.add(fields);
            }
            //根据业务逻辑，将超级表的标签字段定为
            //超级表的标签字段，可以作为子表在超级表里的标识
            List<Fields> tagsFields = new ArrayList<>();
            // 1:设备所属项目id：projectId
            Fields projectIdTags = new Fields();
            projectIdTags.setFieldName("project_id");
            projectIdTags.setDataType(DataTypeEnum.BINARY);
            projectIdTags.setSize(64);
            tagsFields.add(projectIdTags);
            // 2:设备所属分组id：groupId
            Fields groupIdTags = new Fields();
            groupIdTags.setFieldName("group_id");
            groupIdTags.setDataType(DataTypeEnum.BINARY);
            groupIdTags.setSize(64);
            tagsFields.add(groupIdTags);

            //设置超级表表结构列表
            superTableDto.setSchemaFields(schemaFields);
            //设置超级表标签字段列表
            superTableDto.setTagsFields(tagsFields);

            R<?> cstResult = tdEngineService.createSuperTable(superTableDto);
            //创建超级表报错，打印报错信息
            if (cstResult.getCode() != 200) {
                log.error("创建超级表 SuperTable Exception: " + cstResult.getMsg());
            }
        }
    }

    /**
     * 修改产品
     * 
     * @param iotProductInfo 产品
     * @return 结果
     */
    @Override
    public int updateIotProductInfo(IotProductInfo iotProductInfo)
    {
        iotProductInfo.setUpdateTime(DateUtils.getNowDate());
        return iotProductInfoMapper.updateIotProductInfo(iotProductInfo);
    }

    /**
     * 批量删除产品
     * 
     * @param ids 需要删除的产品主键
     * @return 结果
     */
    @Override
    public int deleteIotProductInfoByIds(Integer[] ids)
    {
        return iotProductInfoMapper.deleteIotProductInfoByIds(ids);
    }

    /**
     * 删除产品信息
     * 
     * @param id 产品主键
     * @return 结果
     */
    @Override
    public int deleteIotProductInfoById(Integer id)
    {
        return iotProductInfoMapper.deleteIotProductInfoById(id);
    }

    @Override
    public boolean existByProductKey(String productKey) {
        List<IotProductInfo> productInfos = iotProductInfoMapper.selectIotProductInfoByKeyAndNoId(productKey,null);
        if(CollectionUtil.isNotEmpty(productInfos)){
            return true;
        }else {
            return false;
        }
    }

    @Override
    public boolean existByProductKeyAndId(String productKey, Integer id) {
        List<IotProductInfo> productInfos = iotProductInfoMapper.selectIotProductInfoByKeyAndNoId(productKey,id);
        if(CollectionUtil.isNotEmpty(productInfos)){
            return true;
        }else {
            return false;
        }
    }
}
